package com.disk.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.disk.domain.FolderInformation;
import com.disk.handleResult.DiskMessage;
import com.disk.handleResult.FolderResult;
import com.disk.handleResult.Result;
import com.disk.handleResult.ReturnStatus;
import com.disk.service.FolderService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.File;
import java.util.Date;
import java.util.Objects;

@Service
@Data
public class FolderServiceImpl implements FolderService {
    @Value(value = "${file.root.dir}")
    private String rootDir;

    private String root=rootDir;

    public void setUserRoot(String username){
        File rootFolder = new File(rootDir);
        if(!rootFolder.exists())
        {
            rootFolder.mkdir();
        }
        if (username.isEmpty())
        {
            setRoot(rootDir);
        }
        else {
            String result = rootDir+username+File.separator;
            setRoot(result);
            File newFolder = new File(rootDir, username);
            if(!newFolder.exists())
            {
                newFolder.mkdir();
            }
        }
    }

    /**
     * 创建文件夹
     *
     * @param folderName:文件夹名
     */
    @Override
    public FolderResult createFolder(String folderName) {

        FolderResult folderResult = new FolderResult();
        File newFolder = new File(root, folderName);
        try {
            if (newFolder.exists()) {
                folderResult.setStatus(ReturnStatus.FAIL);
                folderResult.setMessage(DiskMessage.ASK_FOLDER_FAIL);
                folderResult.setFolderName(folderName);
                return folderResult;
            }
            newFolder.mkdir();
            folderResult.setStatus(ReturnStatus.SUCCESS);
            folderResult.setMessage(DiskMessage.CREATE_SUCCESS);
            folderResult.setFolderName(folderName);
        } catch (Exception e) {
            e.printStackTrace();
            folderResult.setStatus(ReturnStatus.FAIL);
            folderResult.setMessage(e.getMessage());
            folderResult.setFolderName(folderName);
        }
        return folderResult;
    }

    /**
     * 删除文件夹
     *
     * @param folderName 文件夹名
     * @param all        是否递归删除文件夹下文件
     */
    @Override
    public FolderResult deleteFolder(String folderName,
                                     @RequestParam(required = false,defaultValue = "yes") String all) {

        FolderResult folderResult = new FolderResult();
        File folder = new File(root, folderName);

        try {
            if (!folder.exists()) {
                folderResult.setStatus(ReturnStatus.FAIL);
                folderResult.setMessage(DiskMessage.ASK_FOLDER_FAIL);
                folderResult.setFolderName(folderName);
                return folderResult;
            }
            if (!folder.isDirectory()) {
                folderResult.setStatus(ReturnStatus.FAIL);
                folderResult.setMessage(DiskMessage.NOT_FOLDER);
                folderResult.setFolderName(folderName);
                return folderResult;
            }
            if (all.equalsIgnoreCase("Y") || all.equalsIgnoreCase("yes") || all.equalsIgnoreCase("true")) {
                // 删除文件夹及所属文件
                deleteFolder(root + "\\" + folderName);
                folderResult.setStatus(ReturnStatus.SUCCESS);
                folderResult.setMessage(DiskMessage.DELETE_SUCCESS);
                folderResult.setFolderName(folderName);
                return folderResult;
            }
            if (Objects.requireNonNull(folder.listFiles()).length > 0) {
                // 文件夹不为空，无法仅删除文件夹
                folderResult.setStatus(ReturnStatus.FAIL);
                folderResult.setMessage("文件夹不为空，无法仅删除文件夹");
                folderResult.setFolderName(folderName);
                return folderResult;
            }

            // 仅删除文件夹
            folder.delete();
            folderResult.setStatus(ReturnStatus.SUCCESS);
            folderResult.setMessage(DiskMessage.DELETE_SUCCESS);
            folderResult.setFolderName(folderName);
        } catch (Exception e) {
            e.printStackTrace();
            folderResult.setStatus(ReturnStatus.FAIL);
            folderResult.setMessage(e.getMessage());
            folderResult.setFolderName(folderName);
        }
        return folderResult;
    }

    /**
     * 更新除文件夹名字
     *
     * @param folderInformation 文件夹信息
     */
    @Override
    public FolderResult updateFolder(FolderInformation folderInformation) {

        FolderResult folderResult = new FolderResult();
        String currentFolderName = folderInformation.getCurrentFolderName();
        String targetFolderName = folderInformation.getTargetFolderName();

        File currentFolder = new File(root, currentFolderName);
        File targetFolder = new File(root, targetFolderName);
        try {
            if (targetFolder.exists()) {
                folderResult.setStatus(ReturnStatus.FAIL);
                folderResult.setMessage(DiskMessage.REPEAT_FOLDER);
                folderResult.setFolderName(targetFolderName);
                return folderResult;
            }
            if (currentFolder.exists()) {
                currentFolder.renameTo(targetFolder);

                folderResult.setStatus(ReturnStatus.SUCCESS);
                folderResult.setMessage(DiskMessage.UPDATE_SUCCESS);
                folderResult.setFolderName(targetFolderName);
                return folderResult;
            }
            folderResult.setStatus(ReturnStatus.FAIL);
            folderResult.setMessage(DiskMessage.ASK_FOLDER_FAIL);
            folderResult.setFolderName(currentFolderName);
        } catch (Exception e) {
            e.printStackTrace();
            folderResult.setStatus(ReturnStatus.FAIL);
            folderResult.setMessage(e.getMessage());
            folderResult.setFolderName(currentFolderName);
        }
        return folderResult;
    }


    /**
     * 获取文件夹下的内容
     *
     * @param folderName 文件夹名
     * @param all        是否包含所有内容，是则获取包含文件夹的所有内容，否则只获取改路径下的文件夹
     */
    @Override
    public FolderResult getFiles(String folderName,
                                 @RequestParam(required = false,defaultValue = "yes")String all) {

        FolderResult folderResult = new FolderResult();
        try {
            File folder = new File(root, folderName);
            if (!folder.exists()) {
                folderResult.setStatus(ReturnStatus.FAIL);
                folderResult.setMessage(DiskMessage.ASK_FOLDER_FAIL);
                folderResult.setFolderName(folderName);
                folderResult.setFiles(new JSONArray());
                return folderResult;
            }

            String[] fileList = folder.list();
            JSONArray list = new JSONArray();
            assert fileList != null;
            for (String item : fileList) {
                File sub = new File(root, folderName + "\\" + item);
                String subName = sub.getName().toLowerCase();
                Date date = new Date(sub.lastModified());

                JSONObject singleFileItem = new JSONObject();
                singleFileItem.put("name", subName);
                singleFileItem.put("date", String.format("%tF%n", date) + " " + String.format("%tT%n", date));
                if (sub.isDirectory()) {
                    singleFileItem.put("path", folderName.equals("/") ? (folderName + item) : folderName + "/" + item);
                    singleFileItem.put("size", "-");
                    singleFileItem.put("type", "folder");
                    list.add(singleFileItem);
                    continue;
                }
                if (!(all.equalsIgnoreCase("Y") || all.equalsIgnoreCase("yes") || all.equalsIgnoreCase("true"))) {
                    continue;
                }
                singleFileItem.put("path", folderName);
                singleFileItem.put("size", sub.length() / 1000 + " kb");
                if (subName.endsWith(".jpg") || subName.endsWith(".jpeg") || subName.endsWith(".png") || subName.endsWith(".bmp") || subName.endsWith(".ico") || subName.endsWith(".psd") || subName.endsWith(".psb") || subName.endsWith(".gif")) {
                    singleFileItem.put("type", "image");
                    list.add(singleFileItem);
                    continue;
                }
                if (subName.endsWith(".mp4") || subName.endsWith(".mov") || subName.endsWith(".3gp") || subName.endsWith(".avi") || subName.endsWith(".mpg") || subName.endsWith(".mpeg") || subName.endsWith(".flv") || subName.endsWith(".mkv") || subName.endsWith(".rm") || subName.endsWith(".rmvb") || subName.endsWith(".wmv")) {
                    singleFileItem.put("type", "video");
                    list.add(singleFileItem);
                    continue;
                }
                if (subName.endsWith(".mp3") || subName.endsWith(".wav") || subName.endsWith(".ogg") || subName.endsWith(".ape") || subName.endsWith(".acc")) {
                    singleFileItem.put("type", "audio");
                    list.add(singleFileItem);
                    continue;
                }
                singleFileItem.put("type", "file");
                list.add(singleFileItem);
            }

            folderResult.setStatus(ReturnStatus.SUCCESS);
            folderResult.setMessage(DiskMessage.ASK_FOLDER_SUCCESS);
            folderResult.setFolderName(folderName);
            folderResult.setFiles(list);
        } catch (Exception e) {
            e.printStackTrace();
            folderResult.setStatus(ReturnStatus.FAIL);
            folderResult.setMessage(e.getMessage());
            folderResult.setFolderName(folderName);
            folderResult.setFiles(new JSONArray());
        }
        return folderResult;
    }

    @Override
    public Result getSpaceInfo() {
        File folder = new File(root);

        try {
            long free = folder.getFreeSpace();
            long total = folder.getTotalSpace();
            String freeString = (free / 1024 / 1024 / 1024) + "G";
            String totalString = (total / 1024 / 1024 / 1024) + "G";

            String message = "可用容量：" + freeString + " 总容量：" + totalString;

            return new Result(true,message);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,e.getMessage());
        }
    }


    private void deleteFolder(String path) {
        File folder = new File(path);
        if (!folder.isFile()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File f : files) {
                    deleteFolder(f.getAbsolutePath());
                }
            }
        }
        folder.delete();
    }
}
